/*
 * Copyright (c) 2025 Industrial Software Feature Database
 */
package com.comac.ins.bomt.repository.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.comac.ins.bomt.common.enums.BizStepEnum;
import com.comac.ins.bomt.common.enums.BomInfoStatusEnum;
import com.comac.ins.bomt.domain.*;
import com.comac.ins.bomt.domain.vo.*;
import com.comac.ins.bomt.mapper.*;
import com.comac.ins.bomt.repository.BomRepository;
import com.comac.ins.common.core.domain.model.LoginUser;
import com.comac.ins.common.biz.utils.BizAssertUtil;
import com.comac.ins.common.core.utils.MapstructUtils;
import com.comac.ins.common.json.utils.JsonUtils;
import com.comac.ins.common.mybatis.helper.BaseEntityHelper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @author zhanghongyi
 * @date 2024/8/13 11:11
 * @description BomRepositoryImpl
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class BomRepositoryImpl implements BomRepository {

    private final BomtBomInfoMapper bomInfoMapper;

    private final BomtOriginalBomV2DetailMapper originalBomDetailMapper;

    private final BomtOriginalBomV2InfoMapper originalBomInfoMapper;

    private final BomtStandardBomDetailMapper standardBomDetailMapper;

    private final BomtStrengthBomDetailMapper strengthBomDetailMapper;

    private final BomtModelStatusDetailMapper modelStatusDetailMapper;

    private final BomtStrengthVsStandardChangeDetailMapper strengthVsStandardChangeDetailMapper;

    private final BomtStatusVsStrengthChangeDetailMapper statusVsStrengthChangeDetailMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<BomInfo> initBomRecords(LoginUser loginUser, List<String> groupTypes, String aircraftModel, String track, BizFileVo fileVo) {
        List<BomInfo> resultList = new ArrayList<BomInfo>();
        for (String groupType : groupTypes) {
            BomInfo bomInfo = new BomInfo();
            BaseEntityHelper.fillCreateByAndUpdateBy(bomInfo, loginUser);
            bomInfo.setAircraftModel(aircraftModel);
            bomInfo.setName(StringUtils.join(Arrays.asList(aircraftModel, groupType), "_"));
            bomInfo.setTrack(track);
            bomInfo.setGroupType(groupType);
            bomInfo.setStatus(BomInfoStatusEnum.DOING.getCode());
            bomInfo.setBizStep(BizStepEnum.OBOM_SBOM_CONVERT.getType());
            int insRet = bomInfoMapper.insert(bomInfo);
            BizAssertUtil.isTrue(1 == insRet, MessageFormat.format("insert record fail {0}", JsonUtils.toJsonString(bomInfo)));
            resultList.add(bomInfo);
        }
        return resultList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<DetailStrengthBom> initStrengthBomDetail(LoginUser loginUser, String aircraftModel, String track, String groupType, List<DetailStrengthBom> details) {
        QueryWrapper<DetailStrengthBom> wrapper = new QueryWrapper<>();
        wrapper.eq("aircraft_model", aircraftModel);
        wrapper.eq("track", track);
        wrapper.eq("group_type", groupType);
        if (strengthBomDetailMapper.selectCount(wrapper) > 0) {
            List<Long> ids = strengthBomDetailMapper.selectList(wrapper).stream().map(DetailStrengthBom::getId).toList();
            strengthBomDetailMapper.deleteBatchIds(ids);
        }
        details.forEach(detail -> {
            BaseEntityHelper.fillCreateByAndUpdateBy(detail, loginUser);
            detail.setId(null);
        });
        //入库
        if (CollectionUtils.isNotEmpty(details)) {
            boolean insRet = strengthBomDetailMapper.insertBatch(details);
            BizAssertUtil.isTrue(insRet, "insert detail fail");
        }
        return details;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<DetailStrengthStandardChange> initStrengthStandardChangeDetail(LoginUser loginUser, String aircraftModel, String track, String groupType, SummaryStrengthStandardChangeVo changeVo) {
        //删除
        QueryWrapper<DetailStrengthStandardChange> wrapper = new QueryWrapper<>();
        wrapper.eq("aircraft_model", aircraftModel);
        wrapper.eq("track", track);
        wrapper.eq("group_type", groupType);
        if (strengthVsStandardChangeDetailMapper.selectCount(wrapper) > 0) {
            List<Long> ids = strengthVsStandardChangeDetailMapper.selectList(wrapper).stream().map(DetailStrengthStandardChange::getId).toList();
            strengthVsStandardChangeDetailMapper.deleteBatchIds(ids);
        }
        //入库
        List<DetailStrengthStandardChange> changeDetailList = changeVo.getChangeDetailList().stream().map(item -> MapstructUtils.convert(item, DetailStrengthStandardChange.class)).toList();
        changeDetailList.forEach(detail -> {
            BaseEntityHelper.fillCreateByAndUpdateBy(detail, loginUser);
            detail.setId(null);
        });
        boolean detailResult = strengthVsStandardChangeDetailMapper.insertBatch(changeDetailList);
        BizAssertUtil.isTrue(detailResult, "insert change detail fail");
        return changeDetailList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<DetailStatusStrengthChange> initStatusStrengthChangeDetail(LoginUser loginUser, String aircraftModel, String track, String groupType, SummaryStatusStrengthChangeVo changeVo) {
        //删除
        QueryWrapper<DetailStatusStrengthChange> wrapper = new QueryWrapper<>();
        wrapper.eq("aircraft_model", aircraftModel);
        wrapper.eq("track", track);
        wrapper.eq("group_type", groupType);
        if (statusVsStrengthChangeDetailMapper.selectCount(wrapper) > 0) {
            List<Long> ids = statusVsStrengthChangeDetailMapper.selectList(wrapper).stream().map(DetailModelStatus::getId).toList();
            statusVsStrengthChangeDetailMapper.deleteBatchIds(ids);
        }
        //入库
        List<DetailStatusStrengthChange> changeDetailList = changeVo.getChangeDetailList().stream().map(item -> MapstructUtils.convert(item, DetailStatusStrengthChange.class)).toList();
        changeDetailList.forEach(detail -> {
            BaseEntityHelper.fillCreateByAndUpdateBy(detail, loginUser);
            detail.setId(null);
        });
        boolean detailResult = statusVsStrengthChangeDetailMapper.insertBatch(changeDetailList);
        BizAssertUtil.isTrue(detailResult, "insert status change detail fail");
        return changeDetailList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<DetailModelStatus> initModelStatusDetail(LoginUser loginUser, String aircraftModel, String track, String groupType, List<DetailModelStatus> details) {
        //删除
        QueryWrapper<DetailModelStatus> wrapper = new QueryWrapper<>();
        wrapper.eq("aircraft_model", aircraftModel);
        wrapper.eq("track", track);
        wrapper.eq("group_type", groupType);
        if (modelStatusDetailMapper.selectCount(wrapper) > 0) {
            List<Long> ids = modelStatusDetailMapper.selectList(wrapper).stream().map(DetailModelStatus::getId).toList();
            modelStatusDetailMapper.deleteBatchIds(ids);
        }
        //入库
        details.forEach(detail -> {
            BaseEntityHelper.fillCreateByAndUpdateBy(detail, loginUser);
            detail.setId(null);
        });
        boolean detailResult = modelStatusDetailMapper.insertBatch(details);
        BizAssertUtil.isTrue(detailResult, "insert change detail fail");
        return details;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<DetailStandardBom> initStandardBomDetail(LoginUser loginUser, String aircraftModel, String track, String groupType, List<DetailStandardBomVo> details) {
        QueryWrapper<DetailStandardBom> wrapper = new QueryWrapper<>();
        wrapper.eq("aircraft_model", aircraftModel);
        wrapper.eq("track", track);
        wrapper.eq("group_type", groupType);
        if (standardBomDetailMapper.selectCount(wrapper) > 0) {
            List<Long> ids = standardBomDetailMapper.selectList(wrapper).stream().map(DetailStandardBom::getId).toList();
            standardBomDetailMapper.deleteBatchIds(ids);
        }
        //入库
        AtomicLong index = new AtomicLong();
        List<DetailStandardBom> records = details.stream().map(
            vo -> {
                DetailStandardBom detailStandardBom = MapstructUtils.convert(vo, DetailStandardBom.class);
                BizAssertUtil.notNull(detailStandardBom, "convert detailStandardBom fail");
                BaseEntityHelper.fillCreateByAndUpdateBy(detailStandardBom, loginUser);
                detailStandardBom.setId(null);
                return detailStandardBom;
            }
        ).toList();
        standardBomDetailMapper.insertBatch(records);
        return records;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateBomWithBizStepAndStatus(BizStepEnum bizStep, BomInfoStatusEnum bomInfoStatus, List<Long> ids) {
        List<BomInfo> bomInfos = bomInfoMapper.selectBatchIds(ids);
        bomInfos.forEach(item -> {
            item.setBizStep(bizStep.getType());
            item.setStatus(bomInfoStatus.getCode());
        });
        boolean result = bomInfoMapper.updateBatchById(bomInfos);
        BizAssertUtil.isTrue(result, "update bom info status fail");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchUpdateBom(List<BomInfo> bomInfos) {
        boolean result = bomInfoMapper.updateBatchById(bomInfos);
        BizAssertUtil.isTrue(result, "update bom info status fail");
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateStrengthDetailCommentByStandardDetail(DetailStandardBom standardBomDetail, String comment) {
        QueryWrapper<DetailStrengthBom> wrapper = new QueryWrapper<>();
        wrapper.eq("aircraft_model", standardBomDetail.getAircraftModel());
        wrapper.eq("track", standardBomDetail.getTrack());
        wrapper.eq("group_type", standardBomDetail.getGroupType());
        wrapper.eq("standard_detail_id", standardBomDetail.getId());
        wrapper.orderByAsc("ord");
        List<DetailStrengthBom> detailList = strengthBomDetailMapper.selectList(wrapper);
        detailList.forEach(item -> item.setNote(comment));
        if (CollectionUtils.isNotEmpty(detailList)) {
            boolean updateRet = strengthBomDetailMapper.updateBatchById(detailList);
            BizAssertUtil.isTrue(updateRet, "update strength detail comment fail");
        }
    }

    @Override
    public void updateBomInfo(BomInfo bomInfo) {
        BizAssertUtil.notNull(bomInfo, "can't find bom info record");
        int updateCnt = bomInfoMapper.updateById(bomInfo);
        BizAssertUtil.isTrue(updateCnt == 1, "update bom info fail");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteStandardBomDetails(List<Long> deleteIds) {
        int delRet = standardBomDetailMapper.deleteBatchIds(deleteIds);
        BizAssertUtil.isTrue(delRet == deleteIds.size(), "delete standard bom detail fail");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteStrengthBomDetails(List<Long> deleteIds) {
        int delRet = strengthBomDetailMapper.deleteBatchIds(deleteIds);
        BizAssertUtil.isTrue(delRet == deleteIds.size(), "delete strength bom detail fail");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifyStandardBomDetails(List<DetailStandardBomVo> modifyDetails) {
        boolean updateRet = standardBomDetailMapper.updateBatchById(MapstructUtils.convert(modifyDetails, DetailStandardBom.class));
        BizAssertUtil.isTrue(updateRet, "update standard bom detail fail");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifyStrengthBomDetails(List<DetailStrengthBomVo> modifyDetails) {
        boolean updateRet = strengthBomDetailMapper.updateBatchById(MapstructUtils.convert(modifyDetails, DetailStrengthBom.class));
        BizAssertUtil.isTrue(updateRet, "update strength bom detail fail");
    }
}
